function elaplace2 % error solving Laplaces equation as a function of N (M=N and M=N/2) % matrix equation solved using CGM % clear all previous variables and plots clear * clf % n_points = number of different N values to use n_points=7; % loop for various values of N (M=N) for ic=1:n_points % set parameters if ic<5 N=10*2^(ic-1)+2; else N=100*2*(ic-4)+2; end; M=N; points(ic)=N-2; % generate grid x=linspace(0,1,N); y=linspace(0,1,M); h=x(2)-x(1); k=y(2)-y(1); alpha=h/k; % generate matrix and RHS of equation A=matrix(alpha,N-2,M-2); b=rhs(x,y,alpha,N-2,M-2); %tic; % use CGM to solve matrix equation v=cgm(A,b); %toc % transform back to u(i,j) u=map(x,y,v,N,M); % calculate exact solution sol=exact(N,M,x,y); % calculate error error(ic)=max(max(abs(u-sol))); end; % loop for various values of N (M=N/2) for ic=1:n_points % set parameters if ic<5 N=10*2^(ic-1)+2; else N=100*2^(ic-4)+2; end; M=(N-2)/2+2; points2(ic)=N-2; % generate grid x=linspace(0,1,N); y=linspace(0,1,M); h=x(2)-x(1); k=y(2)-y(1); alpha=h/k; % generate matrix and RHS of equation A=matrix(alpha,N-2,M-2); b=rhs(x,y,alpha,N-2,M-2); %tic; % use CGM to solve matrix equation v=cgm(A,b); %toc % transform back to u(i,j) u=map(x,y,v,N,M); % calculate exact solution sol=exact(N,M,x,y); % calculate error error2(ic)=max(max(abs(u-sol))); end; % get(gcf) % set(gcf,'Position', [7 477 530 280]); plotsize(530,280) % plot solution loglog(points,error,'-ko','MarkerSize',7) hold on grid on loglog(points2,error2,'-ks','MarkerSize',7) % define axes and legend used in plot xlabel('Number of Points Along x-Axis','FontSize',14,'FontWeight','bold') ylabel('Error','FontSize',14,'FontWeight','bold') legend(' M = N',' M = N/2',1); % have MATLAB use certain plot options (all are optional) set(gca,'MinorGridLineStyle','none') set(gca,'FontSize',14); set(findobj(gcf,'tag','legend'),'FontSize',14,'FontWeight','bold'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % exact solution: assumes gL=gR=gB=0 function sol=exact(N,M,x,y) sol=zeros(N,M); if N<100 modes=200; else modes=400; end; for nn=1:modes np=nn*pi; e6=exp(6)*(-1)^nn; an(nn)=(12/5)*np*( 4*e6*(np^2-36)*(np^2+6) - 672*np^2 - 5*np^4 - 26352)/(36+np^2)^4; % an(nn)=an(nn)/sinh(np); end; for j=1:M-1 for i=1:N s=0; for nn=1:modes np=nn*pi; np1=np*(y(j)-1); np2=np*(y(j)+1); sinh2=(exp(np1)-exp(-np2))/(1-exp(-2*np)); s=s+an(nn)*sinh2*sin(np*x(i)); % s=s+an(nn)*sinh(nn*pi*y(j))*sin(nn*pi*x(i)); end; sol(i,j)=s; end; end; for i=1:N sol(i,M)=gT(x(i)); end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % top BC function (y=1) function g=gT(x) g=x*(1-x)*(4/5-x)*exp(6*x); % right BC function (x=1) function g=gR(y) g=0; % bottom BC function (y=0) function g=gB(x) g=0; % left BC function (x=0) function g=gL(y) g=0; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function for constructing RHS function b=rhs(x,y,alpha,N,M) b=zeros(N*M,1); for i=1:N b(i)=alpha^2*gB(x(i+1))+b(i); it=(M-1)*N+i; b(it)=alpha^2*gT(x(i+1))+b(it); end; for j=1:M it=(j-1)*N+1; b(it)=gL(y(j+1))+b(it); it=j*N; b(it)=gR(y(j+1))+b(it); end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function for creating the matrix A function A=matrix(alpha,N,M) nm=N*M; % generate the diagonal elements D = sparse(1:nm,1:nm,2*(1+alpha^2)*ones(1,nm),nm,nm); % generate the subdiagonal elements SD = sparse(2:nm,1:nm-1,-ones(1,nm-1),nm,nm); for i=N+1:N:nm-1 SD(i,i-1)=0; end; % generate the sub-subdiagonal elements SSD=sparse(N+1:nm,1:nm-N,-alpha^2*ones(1,nm-N),nm,nm); % use symmetry of A to complete construction A=D+SD+SD'+SSD+SSD'; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function for converting back to u(i,j) function u=map(x,y,v,N,M) u=zeros(N,M); for ix=1:N u(ix,1)=gB(x(ix)); u(ix,M)=gT(x(ix)); end; for iy=1:M u(1,iy)=gL(y(iy)); u(N,iy)=gR(y(iy)); end; for j=2:M-1 for i=2:N-1 l=(j-2)*(N-2)+i-1; u(i,j)=v(l); end; end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function for the CGM function x=cgm(A,b) % set CGM parameters nm=length(b); if nm<10000 tol=0.000001; else tol=0.000000001; end; x=zeros(nm,1); % start iteration r=b-A*x; d=r; rr=dot(r,r); error=1; beta=0; counter=1; while error>tol counter=counter+1; q=A*d; alpha=rr/dot(d,q); x=x+alpha*d; r0=r; r=r-alpha*q; rr0=rr; rr=dot(r,r); error=norm(alpha*d,inf)/norm(x,inf); % error=sqrt(rr); beta=rr/rr0; d=r+beta*d; end; fprintf('\n Number of CGM Iterations = %i Error = %e \n\n',counter,error) % subfunction plotsize function plotsize(width,height) siz=get(0,'ScreenSize'); bottom=max(siz(4)-height-95,1); set(gcf,'Position', [2 bottom width height]);